 /*
 *
 *  Copyright (c) 2003 ARM Limited
 *  All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>
#include <asm/cputype.h>
#include <mach/slave_core.h>

#ifdef CONFIG_RTOS_HAL_INVALIDATE_BTB
#define RTOS_FLAG_IN_ASM
#include <linux/hal/flag_cmdline.h>
#endif

#if (! defined(CONFIG_HOTPLUG_CPU)) || (! defined(CONFIG_RTOS_HAL_BUGFIX))
	__INIT
#endif

/*
 * Versatile Express specific entry point for secondary CPUs.  This
 * provides a "holding pen" into which all secondary cores are held
 * until we're ready for them to initialise.
 */

#ifdef CONFIG_RTOS_ONT_SMP_WITH_THUMB
	.arm
#endif
	.global hisi_secondary_startup_end

#ifdef CONFIG_RTOS_ONT_SMP_WITH_THUMB
	.arm
#endif
ENTRY(hisi_secondary_startup)

	@movw    r0, #0x0878             @ add SCTLR init */
	@movt    r0, #0x00c5             @ initial SCTLR because bootloader is different
	@mcr     p15, 0, r0, c1, c0, 0
	@isb

#ifndef CONFIG_CPU_ENDIAN_BE8
	setend le       @set little end
#else
	setend be       @set big end
#endif

#ifdef CONFIG_RTOS
#ifdef CONFIG_CORTEX_A15
        @about cache ecc config: L2CTLR, L2ACTLR, L2PFR, ACTLR2
        ldr     r1, =0x03201400                 @ L2CTLR
        ldr     r2, =0x04000000                 @ L2ACTLR
        mcr     p15, 1, r1, c9, c0, 2           @ write L2CTLR
        mcr     p15, 1, r2, c15, c0, 0          @ write L2ACTLR

        ldr     r1, =0x000009b0                 @ L2PFR
        ldr     r2, =0x80000000                 @ ACTLR2
        mcr     p15, 1, r1, c15, c0, 3          @ write L2PFR
        mcr     p15, 1, r2, c15, c0, 4          @ write ACTLR2

        @A15 need to set ACTLR bit[31] to enable snoop-delayed exclusive handling
        mrc     p15, 0, r1, c1, c0, 1
        orr     r1, r1, #0x80000000

        mcr     p15, 0, r1, c1, c0, 1

#ifdef CONFIG_RTOS_HAL_INVALIDATE_BTB
	mov	r6, sp

	adr_l	r7, swapper_pg_dir
	lsr	r7, #ALIGE_1M_SHIFT
	lsl	r7, #ALIGE_1M_SHIFT
	add	sp, r7, #HISI_NONSEC_STACK_ADDR

	stmfd	sp!, {r0-r3, r9, ip, lr}
	adr_l	r0, rtos_flag
	bl	process_rtos_flag
	ldmfd   sp!, {r0-r3, r9, ip, lr}

	mov     sp, r6

	dsb
	isb
#endif

#endif
#endif


#ifdef CONFIG_RTOS_CPU_MODE
        cps     #22                             @/* go to monitor mode */
        mov     r6, sp
        ldr     sp, =HISI_NONSEC_STACK_ADDR
        stmfd   sp!, {r0-r3, r6, ip, lr}
        bl      hisi_switch_nonsec              @/* set system for non secure, for slave core */
        ldmfd   sp!, {r0-r3, r6, ip, lr}
        dsb
        isb
        mov     sp, r6

        @ set the cpu to SVC32 mode
        mrs     r0, cpsr
        bic     r0, r0, #0x1f
        orr     r0, r0, #0xd3                   @/*Disable irq&fiq, set svc model*/
        orr     r0, r0, #0x00000100             @/*Disable async abort*/
        msr     cpsr, r0
        mov     r0, r0
#endif

	mrc	p15, 0, r0, c0, c0, 5
	and	r0, r0, #MPIDR_HWID_BITMASK		@ get affinity level 0 ~ 3
	adr_l   r6, pen_release				@ pen_release saved mpidr[23:0]

#ifdef CONFIG_RTOS_HAL_CORE_RESET_LOG
	adr_l	r7, core_reset_log_addr
	ldr	r7, [r7]
	cmp	r7, 0
	beq	pen
	ldr	r10, =0x41		@ EKBOX_RESERVE_SIZE
	add	r7, r7, r10, lsr #1	@ skip fiq
	add	r7, r7, r10, lsr #2	@ skip slave boot entry

	ldr	r10, [r6]
	mov	r6, #0x41		@'A'
	add	r6, r6, r10
	strb	r6, [r7, r10]

	adr_l	r6, pen_release
#endif
pen:	ldr	r7, [r6]
	cmp	r7, r0
	bne	pen

	/*
	 * we've been released from the holding pen: secondary_stack
	 * should now contain the SVC stack for this core
	 */
	b	secondary_startup
	.align

hisi_secondary_startup_end:
#ifdef CONFIG_RTOS_ONT_SMP_WITH_THUMB
ENDPROC(hisi_secondary_startup)
#endif
